#ifndef __DAEMONIZE_H__
#define __DAEMONIZE_H__

#include <fcntl.h>
#include <stdio.h>
#include <execinfo.h>
#include <signal.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include "LibUtil.h"

static std::string g_szDumpName = "test_dump";

class Daemonize
{
public:
    class SignalHolker
    {
    public:
        SignalHolker()
        {
            signal( SIGSEGV, OnSignal);   
            signal( SIGFPE,  OnSignal);
            signal( SIGILL,  OnSignal);
            signal( SIGINT,  OnSignal);
            signal( SIGTERM, OnSignal);
            signal( SIGABRT, OnSignal);
            signal( SIGXFSZ, OnSignal);
            signal( SIGPIPE, OnSignal);
        }
        ~SignalHolker() { };
    private:
        static void OnSignal(int signo)
        {
            //ExitServer(signo);
        }
    };

    friend class SignalHolker;
    friend void ExitServer(int signo)
    {
        signal( SIGSEGV, 0 );   
        signal( SIGFPE,  0 );
        signal( SIGILL,  0 );
        signal( SIGINT,  0 );
        signal( SIGTERM, 0 );
        signal( SIGABRT, 0 );
        signal( SIGXFSZ, 0 );
        signal( SIGPIPE, 0  );
        printf("Recv Sys Signal[%d], Sys error: [%s] ",signo, strerror(errno));

        /*
        if(WriteCoreDump(g_szDumpName.c_str()) == -1)
        {
	        void*  dump_array[100];
	        int n_size  = ::backtrace( dump_array, 100 );
	        int dump_fd = ::open( DUMP_LOG,  O_WRONLY | O_APPEND | O_CREAT, 0644 );

	        if ( n_size > 0 && dump_fd != -1 )
	        {
		        ::backtrace_symbols_fd( dump_array, n_size, dump_fd );
		        ::close( dump_fd );
	        }
    
        }
        */
        ::exit(0);
    }

    Daemonize(bool bDeamon = true):m_bDeamon(bDeamon)
    {
        if(m_bDeamon)
        {
            pid_t other_pid;
            std::string szPath = "test.pid";
            m_pfh  = pidfile_open( szPath.c_str(), 0600, &other_pid );
            if (NULL == m_pfh)
            {
                if(errno == EEXIST)
                {
                    printf("Daemon already running, pid: %d",(int)other_pid);
                }
            }

            if(daemon(1, 0))
            {
                printf("%s","daemon() failed");
            }

            pidfile_write( m_pfh );
        }
    }
    ~Daemonize()
    {
        if(m_pfh && m_bDeamon)
        {
            if(pidfile_remove(m_pfh) == -1)
            {
                printf("Can not remove pid file, %s", strerror(errno));
            }
            pidfile_close( m_pfh );

        }
    }

private:
    bool                    m_bDeamon;
    static SignalHolker     m_sSignalHoker;
    struct pidfh*           m_pfh;  
};
#endif
